package com.ruoyi.dynamic.service.impl;


import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.core.constant.SecurityConstants;
import com.ruoyi.common.core.constant.UserBalanceConstants;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.enums.CacheKey;
import com.ruoyi.common.core.pojo.result.PageUtils;
import com.ruoyi.common.core.pojo.result.Pages;
import com.ruoyi.common.core.utils.CollectionUtils;
import com.ruoyi.common.core.utils.CommonUtils;
import com.ruoyi.common.core.utils.DateUtils;
import com.ruoyi.common.redis.cache.CacheTemplate;
import com.ruoyi.dynamic.mapper.RoomAuctionMapper;
import com.ruoyi.dynamic.model.constant.DynamicConstant;
import com.ruoyi.dynamic.model.constant.RoomChatRoomKvConstant;
import com.ruoyi.dynamic.model.pojo.entity.Room;
import com.ruoyi.dynamic.model.pojo.entity.RoomAuction;
import com.ruoyi.dynamic.model.pojo.request.app.*;
import com.ruoyi.dynamic.model.pojo.result.app.*;
import com.ruoyi.dynamic.service.IMessageService;
import com.ruoyi.dynamic.service.IRoomAuctionService;
import com.ruoyi.dynamic.service.IRoomService;
import com.ruoyi.dynamic.service.IRoomSetService;
import com.ruoyi.system.api.RemoteAppUserService;
import com.ruoyi.system.api.model.request.AppUserBalanceAocRequest;
import com.ruoyi.system.api.model.request.AppUserBalanceBatchOpetRequest;
import com.ruoyi.system.api.model.user.AppUser;
import com.ruoyi.system.api.model.user.AppUserChum;
import io.rong.RongCloud;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;

/**
 * <p>
 * 房间心动拍拍 服务实现类
 * </p>
 *
 * @author Gnc
 * @since 2024-12-24
 */
@Slf4j
@Service
public class RoomAuctionServiceImpl extends ServiceImpl<RoomAuctionMapper, RoomAuction> implements IRoomAuctionService {

    @Autowired
    private RemoteAppUserService remoteAppUserService;
    @Autowired
    private IRoomService iRoomService;
    @Autowired
    private IRoomSetService iRoomSetService;
    @Autowired
    private RongCloud rongCloud;
    @Autowired
    private IMessageService iMessageService;
    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @Override
    public boolean applyChum(AppRoomChumApplyRequest request, Long userId) {
        Room verify = iRoomService.verify(request.getRoomId());
        Assert.isTrue(!verify.getUserId().equals(userId), "您是主持无法申请");

        if (request.getAuctionType().equals(DynamicConstant.AuctionType.OTHER)) {
            Assert.isTrue(StringUtils.hasText(request.getContent()), "拍卖内容不能为空");
        }
        R<AppUser> userInfo = remoteAppUserService.getUserInfo(userId, SecurityConstants.APP);
        AppUser user = userInfo.getData();
        Assert.notNull(user, "用户不存在");

        AppUserChum data = null;
        if (!request.getUserChumId().equals(0L)) {
            R<AppUserChum> userChumInfo = remoteAppUserService.getUserChumInfo(request.getUserChumId(), SecurityConstants.APP);
            data = userChumInfo.getData();
            Assert.notNull(user, "用户密友不存在");
        }

        AppRoomSetResult set = iRoomSetService.getUserRoomSet(verify.getUserId());
        ;
        RoomAuction roomAuction = new RoomAuction();
        roomAuction.setAuctionType(request.getAuctionType());
        roomAuction.setChumId(Optional.ofNullable(data).orElse(new AppUserChum()).getChumId());
        roomAuction.setUserId(userId);
        roomAuction.setChumName(Optional.ofNullable(data).orElse(new AppUserChum()).getChumName());
        roomAuction.setContent(request.getContent());
        roomAuction.setMoney(request.getMoney());
        roomAuction.setColorText(Optional.ofNullable(data).orElse(new AppUserChum()).getChumColorText());
        roomAuction.setUserChumId(request.getUserChumId());
        if (request.getAuctionType().equals(DynamicConstant.AuctionType.CHUM)) {
            roomAuction.setStatus(set.getIsRelationCheck());
        }
        if (request.getAuctionType().equals(DynamicConstant.AuctionType.OTHER)) {
            roomAuction.setStatus(set.getIsElseCheck());
        }
        roomAuction.setStatus(DynamicConstant.CheckStatus.NO);
        roomAuction.setRoomId(request.getRoomId());
        roomAuction.setUserName(user.getNickName());
        roomAuction.setUserPhoto(user.getPhoto());
        roomAuction.setCreateTime(new Date());
        if (save(roomAuction)) {

            String key = CacheKey.ROOM_MAI.getKey(String.valueOf(verify.getUserId()));
            String cacheKey = key.replaceAll("\\{roomNumber}", String.valueOf(verify.getId()));
            AppRoomMaiUserResult result = CacheTemplate.getCache(cacheKey, AppRoomMaiUserResult.class);
            iMessageService.sendCustomMessage(verify.getUserId().toString(), verify.getGroupId(),
                    RoomChatRoomKvConstant.RC_ALL_BROADCAST_MSG, result, RoomChatRoomKvConstant.ROOM_AUTION_APPLY);
        }
        return true;

    }

    @Override
    public Pages<AppRoomAuctionResult> listPage(AppRoomAuctionSearchRequest request, Long userId) {
        Page<RoomAuction> roomAuctionPage = PageUtils.initPage(request, RoomAuction.class);

        Page<RoomAuction> page = lambdaQuery()
                .eq(request.isCheck(), RoomAuction::getStatus, DynamicConstant.CheckStatus.NO)
                .in(!request.isCheck(), RoomAuction::getStatus, DynamicConstant.CheckStatus.YES, DynamicConstant.CheckStatus.START)
                .eq(RoomAuction::getRoomId, request.getRoomId())
                .eq(!CommonUtils.isNull(request.getAuctionType()), RoomAuction::getAuctionType, request.getAuctionType())
                .orderByAsc(RoomAuction::getCreateTime)
                .page(roomAuctionPage);

        List<AppRoomAuctionResult> collect = page.getRecords().stream().map(res -> {
            AppRoomAuctionResult result = new AppRoomAuctionResult();
            BeanUtils.copyProperties(res, result);
            result.setMy(userId.equals(res.getUserId()));
            result.setBeforeTime(DateUtils.format(res.getCreateTime()));
            return result;
        }).collect(Collectors.toList());

        return PageUtils.pages(page, collect);
    }

    @Override
    public boolean check(AppRoomAuctionCheckRequest request, Long userId) {
        Room verify = iRoomService.verify(request.getRoomId());
        Assert.isTrue(verify.getUserId().equals(userId), "您无权操作");
        RoomAuction auction = this.verify(request.getId());
        Assert.isTrue(auction.getStatus().equals(DynamicConstant.CheckStatus.NO), "此记录已审核");
        auction.setStatus(request.getStatus());
        return updateById(auction);
    }

    @Override
    public RoomAuction verify(Long id) {
        Optional<RoomAuction> roomAuction = lambdaQuery()
                .eq(RoomAuction::getId, id)
                .oneOpt();
        Assert.isTrue(roomAuction.isPresent(), "此拍拍记录不存在");
        return roomAuction.get();
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void startAuction(Long userId, AppRoomAuctionStartRequest request) {
        Room verify = iRoomService.verify(request.getRoomId());
        Assert.isTrue(verify.getUserId().equals(userId), "您无权操作");

        Long count = lambdaQuery()
                .eq(RoomAuction::getStatus, DynamicConstant.CheckStatus.START)
                .eq(RoomAuction::getRoomId, request.getRoomId())
                .count();
        Assert.isTrue(count == 0, "当前房间还有未结束的拍拍");

        RoomAuction auction = this.verify(request.getId());
        Assert.isTrue(auction.getStatus().equals(DynamicConstant.CheckStatus.YES), "此记录无法开始");
        auction.setStatus(DynamicConstant.CheckStatus.START);
        updateById(auction);

        iMessageService.setRoomChatRoomAttr(verify.getGroupId(), verify.getUserId().toString(), RoomChatRoomKvConstant.ROOM_AUCTION_RANK, "[]", 0, "", "");
        //删除之前拍拍结果的key
        iMessageService.removeRoomKV(verify.getGroupId(), verify.getUserId().toString(), RoomChatRoomKvConstant.ROOM_AUTION_RESULT, "", "");
        //发送redis过期事件
        CacheTemplate.setCacheExpire(RoomChatRoomKvConstant.ROOM_AUTION_KEY + auction.getId(), auction.getId(), Long.valueOf(auction.getAutionTime()), TimeUnit.SECONDS);
        //设置当天聊天室属性:设置当前拍卖人
        iMessageService.setRoomChatRoomAttr(verify.getGroupId(), verify.getUserId().toString(), RoomChatRoomKvConstant.ROOM_AUCTION, JSONObject.toJSONString(auction), 0, "", "");
    }

    @Override
    public void over(Long id) {
        RoomAuction auction = getById(id);
        auction.setStatus(DynamicConstant.CheckStatus.END);
        updateById(auction);
        Room room = iRoomService.getById(auction.getRoomId());

        String key = CacheKey.ROOM_MOMENT_RANK.getKey(String.valueOf(auction.getUserId()));
        String cacheKey = key.replaceAll("\\{roomNumber}", String.valueOf(auction.getRoomId()));

        ZSetOperations<String, String> setOperations = redisTemplate.opsForZSet();
        Set<String> stringSet = setOperations.reverseRange(cacheKey, 0, -1);

        //竞拍失败者退还钻石
        List<AppUserBalanceAocRequest> requests = CollectionUtils.emptyList();

        Set<Long> failUserIds = stringSet.stream().map(res -> {
            //退还钻石
            Double score = setOperations.score(cacheKey, res);
            AppUserInfoResult appUserInfoResult = JSONObject.parseObject(res, AppUserInfoResult.class);

            AppUserBalanceAocRequest aocRequest = new AppUserBalanceAocRequest();
            aocRequest.setUserId(appUserInfoResult.getId());
            aocRequest.setMoney(BigDecimal.valueOf(score));
            aocRequest.setRemark("心动拍拍 竞拍失败 钻石退还");
            requests.add(aocRequest);

            appUserInfoResult.setContrNum(BigDecimal.valueOf(score));
            return appUserInfoResult.getId();
        }).collect(Collectors.toSet());

        Set<Long> successUserIds = CollectionUtils.emptySet();
        if (!requests.isEmpty()) {
            AppUserBalanceAocRequest request = requests.get(0);
            if (request.getMoney().doubleValue() >= auction.getMoney().doubleValue()) {
                //第一名竞拍成功则设置密友关系
                successUserIds.add(request.getUserId());
                failUserIds.remove(request.getUserId());
                requests.remove(request);

                if (auction.getAuctionType().equals(DynamicConstant.AuctionType.CHUM)) {
                    this.successAuction(auction, request.getUserId());
                }
            }
        }

        /*请求内部接口增加失败者的钻石*/
        if (!requests.isEmpty()) {
            AppUserBalanceBatchOpetRequest batchOpetRequest = new AppUserBalanceBatchOpetRequest();
            batchOpetRequest.setType(UserBalanceConstants.BalanceType.balance);
            batchOpetRequest.setBalTypel(UserBalanceConstants.BalanceType.balance);
            batchOpetRequest.setRequests(requests);

            remoteAppUserService.aocBalanceByBatch(batchOpetRequest, SecurityConstants.APP);
        }
        /*清空记录*/
        CacheTemplate.clear(cacheKey);
//        iMessageService.removeRoomKV(room.getGroupId(), room.getUserId().toString(), RoomChatRoomKvConstant.ROOM_AUCTION_RANK, "", "");
        AppRoomAuctionInfoResult build = AppRoomAuctionInfoResult.builder()
                .userId(auction.getUserId())
                .chumId(auction.getChumId())
                .chumName(auction.getChumName())
                .content(auction.getContent())
                .money(auction.getMoney())
                .status(auction.getStatus())
                .userPhoto(auction.getUserPhoto())
                .userName(auction.getUserName())
                .auctionType(auction.getAuctionType())
                .colorText(auction.getColorText())
                .autionTime(auction.getAutionTime())
                .failIds(failUserIds)
                .successIds(successUserIds)
                .build();

        iMessageService.setRoomChatRoomAttr(room.getGroupId(), room.getUserId().toString(),
                RoomChatRoomKvConstant.ROOM_AUCTION, JSONObject.toJSONString(auction), 0, "", "");

        iMessageService.setRoomChatRoomAttr(room.getGroupId(), room.getUserId().toString(),
                RoomChatRoomKvConstant.ROOM_AUTION_RESULT, JSONObject.toJSONString(build), 0, "", "");
    }

    @Override
    public AppRoomAuctionGiftResult lookDiff(Long userId, AppRoomAuctionStartRequest request) {
        RoomAuction auction = verify(request.getId());
        AppUserInfoResult cache = CacheTemplate.getCache(CacheKey.USER_INFO.getKey(String.valueOf(userId)), AppUserInfoResult.class);

        String key = CacheKey.ROOM_MOMENT_RANK.getKey(String.valueOf(auction.getUserId()));
        String cacheKey = key.replaceAll("\\{roomNumber}", String.valueOf(auction.getRoomId()));

        ZSetOperations<String, String> setOperations = redisTemplate.opsForZSet();
        Set<String> stringSet = setOperations.reverseRange(cacheKey, 0, 0);

        List<AppUserInfoResult> appUserInfoResults = stringSet.stream().map(res -> {
            Double score = setOperations.score(cacheKey, res);
            AppUserInfoResult appUserInfoResult = JSONObject.parseObject(res, AppUserInfoResult.class);
            appUserInfoResult.setContrNum(BigDecimal.valueOf(score));
            return appUserInfoResult;
        }).collect(Collectors.toList());

        BigDecimal myContrNum = BigDecimal.ZERO;
        Double score = setOperations.score(cacheKey, JSONObject.toJSONString(cache));
        if (!CommonUtils.isNull(score)) {
            myContrNum = BigDecimal.valueOf(score);
        }

        if (appUserInfoResults.isEmpty()) {
            return AppRoomAuctionGiftResult.builder()
                    .diffContrNum(myContrNum)
                    .build();
        }

        AppUserInfoResult result = appUserInfoResults.get(0);
        return AppRoomAuctionGiftResult.builder()
                .userId(result.getId())
                .userPhoto(result.getPhoto())
                .contrNum(result.getContrNum())
                .diffContrNum(result.getContrNum().subtract(myContrNum))
                .build()
                ;
    }

    @Override
    public void successAuction(RoomAuction auction, Long userId) {
        R<Boolean> booleanR = remoteAppUserService.setChum(auction.getUserChumId(), userId, SecurityConstants.APP);
        Boolean data = booleanR.getData();
        log.info("设置密友关系...data={}", booleanR.getData());
    }

    @Override
    public AppAuctionInfoResult info(Long id, Long userId) {
        RoomAuction verify = verify(id);
        AppAuctionInfoResult result = new AppAuctionInfoResult();
        BeanUtils.copyProperties(verify, result);
        Integer cacheTtl = CacheTemplate.getCacheTtl(RoomChatRoomKvConstant.ROOM_AUTION_KEY + verify.getId());
        result.setResidueTime(cacheTtl);
        return result;
    }


    public static void main(String[] args) {
        String key = "room-aution";
        String key1 = "room-aution1";
        System.out.println(key1.contains(key));

    }

}
